package busterminal.command.bus;

import busterminal.command.AbstractCommand;
import busterminal.entity.Bus;
import busterminal.entity.BusModel;
import busterminal.entity.service.PurposeType;
import busterminal.exception.BusinessException;
import busterminal.persistence.BusDAO;
import busterminal.persistence.BusModelDAO;
import busterminal.services.ServiceLocator;
import java.util.Arrays;
import java.util.List;

/**
 * Класс, реализующий действие: обновить информацию про автобус
 */
public class UpdateBusCommand extends AbstractCommand {

    /**
     * Имя параметра "Идентификатор автобуса"
     */
    private final static String PARAM_BUS_ID = "Bus ID";
    /**
     * Имя параметра "Новый государственный номер"
     */
    private final static String PARAM_NEW_STATE_NUMBER = "New state number";
    /**
     * Имя параметра "Новая модель автобуса"
     */
    private final static String PARAM_NEW_BUS_MODEL_ID = "New bus model id";
    /**
     * Имя параметра "Новый год начала эксплуатации"
     */
    private final static String PARAM_NEW_START_YEAR_OF_EXPLOITATION = "New start year of exploitation";
    /**
     * Имя параметра "Новое назначение автобуса"
     */
    private final static String PARAM_NEW_PURPOSE_TYPE = "New purpose type";

    /**
     * Конструктор по умолчанию
     */
    public UpdateBusCommand() {
        super("Update info about bus");
    }

    /**
     * Выполнить команду: обновить информацию про автобус (изменение государственного номера)
     */
    @Override
    public void execute() {
        BusDAO busDAO = ServiceLocator.getService(BusDAO.class);
        String parametrId = parameters.get(PARAM_BUS_ID);
        int ID;
        try {
            ID = Integer.parseInt(parametrId);
        } catch(Exception e) {
            throw new BusinessException("Invalid bus ID='" + parametrId + "';" + e.toString(), e);
        }
        Bus bus = busDAO.read(ID);
        bus.setStateNumber(parameters.get(PARAM_NEW_STATE_NUMBER));
        
        String paramBusModelId = parameters.get(PARAM_NEW_BUS_MODEL_ID);
        int busModelId;
        try {
            busModelId = Integer.parseInt(paramBusModelId);
        } catch (Exception e) {
            throw new BusinessException("Invalid bus model id='" + paramBusModelId + "'; " + e.toString(), e);
        }
        BusModel busModel = ServiceLocator.getService(BusModelDAO.class).read(busModelId);
        if (busModel == null) {
            throw new BusinessException("Cannot find bus model with id='" + busModelId + "'");
        }
        bus.setBusModel(busModel);
        
        String paramStartYearOfExploitation = parameters.get(PARAM_NEW_START_YEAR_OF_EXPLOITATION);
        int startYearOfExploitation;
        try {
            startYearOfExploitation = Integer.parseInt(paramStartYearOfExploitation);
        } catch(Exception e) {
            throw new BusinessException("Invalid start year of exploitation='" + paramStartYearOfExploitation + "'; " + e.toString(), e);
        }
        bus.setStartYearOfExploitation(startYearOfExploitation);
                
        try {
            bus.setPurposeType(PurposeType.valueOf(parameters.get(PARAM_NEW_PURPOSE_TYPE).toUpperCase()));
        } catch (Exception e) {
            throw new BusinessException("Incorrect purpose type: '" + parameters.get(PARAM_NEW_PURPOSE_TYPE) + "'; " + e.toString(), e);
        }              
                
        busDAO.update(bus);
    }

    /**
     * Получить список имён параметров
     * @return список имён параметров
     */
    @Override
    public List<String> getParametersNames() {
        return Arrays.asList(PARAM_BUS_ID, PARAM_NEW_STATE_NUMBER, PARAM_NEW_BUS_MODEL_ID, PARAM_NEW_START_YEAR_OF_EXPLOITATION, PARAM_NEW_PURPOSE_TYPE);
    }

    /**
     * Вывести список доступных вариантов параметра с фиксированным набором значений
     * @param parameterName имя параметра с фиксированным набором значений
     */
    @Override
    public void showAccessableVariants(String parameterName) {
        if (PARAM_NEW_PURPOSE_TYPE.equals(parameterName)) {
            System.out.println("Accessable variants: " + PurposeType.getValues());
        }
    }    
}
